import asyncio
import os
import json
import aiohttp
from edge_tts import Communicate, VoicesManager

class TTSEngine:
    def __init__(self):
        self.voices = []
        self.voice_list = []
        self.current_voice = ""
        self.load_voices()
        self.set_default_voice()

    def set_default_voice(self):
        """设置默认语音为Yunjian"""
        yunjian_voices = [v for v in self.voice_list if 'Yunjian' in v['ShortName']]
        if yunjian_voices:
            self.current_voice = yunjian_voices[0]['ShortName']
            print(f"已选择默认语音: {self.current_voice}")
        elif self.voice_list:
            self.current_voice = self.voice_list[0]['ShortName']
            print(f"未找到Yunjian语音，已选择: {self.current_voice}")
        else:
            self.current_voice = "zh-CN-YunjianNeural"
            print(f"使用备用Yunjian语音: {self.current_voice}")

    def load_voices(self):
        """加载可用的语音列表并翻译为中文"""
        try:
            loop = asyncio.new_event_loop()
            asyncio.set_event_loop(loop)
            voices_manager = loop.run_until_complete(VoicesManager.create())
            self.voices = voices_manager.voices
            loop.close()
            
            self.voice_list = [voice for voice in self.voices if 'zh-' in voice['ShortName']]
            if not self.voice_list:
                self.voice_list = self.voices
                
            print("可用语音列表:")
            for i, voice in enumerate(self.voice_list):
                print(f"{i}: {voice['ShortName']} ({voice['Gender']})")
            
        except Exception as e:
            print(f"加载语音列表失败: {e}")
            self.voice_list = [
                {"ShortName": "zh-CN-XiaoxiaoNeural", "Gender": "Female", "Locale": "zh-CN", "FriendlyName": "晓晓(女)"},
                {"ShortName": "zh-CN-YunxiNeural", "Gender": "Male", "Locale": "zh-CN", "FriendlyName": "云希(男)"},
                {"ShortName": "zh-CN-YunjianNeural", "Gender": "Male", "Locale": "zh-CN", "FriendlyName": "云健(男)"},
                {"ShortName": "zh-CN-YunyangNeural", "Gender": "Male", "Locale": "zh-CN", "FriendlyName": "云扬(男)"},
                {"ShortName": "zh-CN-XiaoyiNeural", "Gender": "Female", "Locale": "zh-CN", "FriendlyName": "晓伊(女)"},
                {"ShortName": "zh-CN-YunyeNeural", "Gender": "Female", "Locale": "zh-CN", "FriendlyName": "云叶(女)"},
                {"ShortName": "zh-CN-liaoning-XiaobeiNeural", "Gender": "Female", "Locale": "zh-CN-liaoning", "FriendlyName": "辽宁晓贝(女)"}
            ]

    def get_voice_names(self):
        """获取中文语音名称列表"""
        name_map = {
            "zh-CN-XiaoxiaoNeural": "晓晓(女)",
            "zh-CN-YunxiNeural": "云希(男)",
            "zh-CN-YunjianNeural": "云健(男)",
            "zh-CN-YunyangNeural": "云扬(男)",
            "zh-CN-XiaoyiNeural": "晓伊(女)",
            "zh-CN-YunyeNeural": "云叶(女)",
            "zh-CN-liaoning-XiaobeiNeural": "辽宁晓贝(女)",
        }
        
        names = []
        for voice in self.voice_list:
            short_name = voice['ShortName']
            friendly_name = name_map.get(short_name, short_name)
            gender = "男" if "Male" in voice.get('Gender', '') else "女"
            names.append(f"{friendly_name} ({gender})")
        
        return names

    def set_voice(self, index):
        """设置当前语音"""
        if 0 <= index < len(self.voice_list):
            self.current_voice = self.voice_list[index]['ShortName']
            print(f"已选择语音: {self.current_voice}")

    async def text_to_speech(self, text, output_file, rate="+0%", volume="+0%", proxy=None, retries=3):
        """将文本转换为语音并保存到文件（纯文本模式）"""
        for attempt in range(retries):
            try:
                print(f"生成语音 (尝试 {attempt+1}/{retries}): {text[:30]}...")
                
                # 直接使用文本，不生成SSML
                communicate = Communicate(
                    text=text,
                    voice=self.current_voice,
                    rate=rate,
                    volume=volume,
                    proxy=proxy
                )
                
                # 保存语音文件
                await communicate.save(output_file)
                
                print(f"语音已保存到: {output_file}")
                return True, ""
            except Exception as e:
                error_msg = str(e)
                print(f"Edge-TTS失败 (尝试 {attempt+1}/{retries}): {error_msg}")
                
                # 如果是最后一次尝试，返回错误
                if attempt == retries - 1:
                    return False, error_msg
                
                # 等待一段时间后重试
                await asyncio.sleep(2 ** attempt)  # 指数退避策略
        
        return False, "所有重试失败"